home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Devices and Hardware / Velocity Engine / VelEng Wavelet / source / CTransformPane.cp < prev    next >
Encoding:
Text File  |  2000-09-28  |  10.6 KB  |  429 lines  |  [TEXT/CWIE]

  1. /*
  2.     Disclaimer:    IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
  3.                 ("Apple") in consideration of your agreement to the following terms, and your
  4.                 use, installation, modification or redistribution of this Apple software
  5.                 constitutes acceptance of these terms.  If you do not agree with these terms,
  6.                 please do not use, install, modify or redistribute this Apple software.
  7.  
  8.                 In consideration of your agreement to abide by the following terms, and subject
  9.                 to these terms, Apple grants you a personal, non-exclusive license, under Apple’s
  10.                 copyrights in this original Apple software (the "Apple Software"), to use,
  11.                 reproduce, modify and redistribute the Apple Software, with or without
  12.                 modifications, in source and/or binary forms; provided that if you redistribute
  13.                 the Apple Software in its entirety and without modifications, you must retain
  14.                 this notice and the following text and disclaimers in all such redistributions of
  15.                 the Apple Software.  Neither the name, trademarks, service marks or logos of
  16.                 Apple Computer, Inc. may be used to endorse or promote products derived from the
  17.                 Apple Software without specific prior written permission from Apple.  Except as
  18.                 expressly stated in this notice, no other rights or licenses, express or implied,
  19.                 are granted by Apple herein, including but not limited to any patent rights that
  20.                 may be infringed by your derivative works or by other works in which the Apple
  21.                 Software may be incorporated.
  22.  
  23.                 The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
  24.                 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
  25.                 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  26.                 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
  27.                 COMBINATION WITH YOUR PRODUCTS.
  28.  
  29.                 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
  30.                 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  31.                 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.                 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
  33.                 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
  34.                 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
  35.                 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36. */
  37.  
  38. // CTransformPane
  39.  
  40. #include "CTransformPane.h"
  41.  
  42. #include <LProgressBar.h>
  43.  
  44. #if __VEC__
  45. #include "vWavelet_int.h"
  46. #endif
  47.  
  48. #include "sWavelet_int.h"
  49.  
  50. #define WAVELET_32_DEPTH        3
  51.  
  52. #define DO_TT6_TRACE            0
  53.  
  54. #define SAVE_WAVELET            0
  55.  
  56. #define REPORT_Y_MSE            0
  57.  
  58. #define TIME_BURT                1
  59.  
  60. #define BURT_LOOPS                100
  61.  
  62. #define BURT_DEPTH                3
  63.  
  64. #define SHOW_U_TRANSORMS        0
  65. #define SHOW_Y_TRANSORMS        0
  66.  
  67. #define REPORT_BURT_MSE            0
  68.  
  69.  
  70. #if DO_TT6_TRACE
  71. #include "pitsTT6libv.h"
  72. #endif
  73.  
  74.  
  75. //////////////////////////////////////////////////////////////////////////////////////////
  76. //    Quantize routine adjusts 16-bit wavelet data so that its appearance makes more
  77. // sense for display.  It adjusts min and max based on quadrants for wavelet data of
  78. // a certain depth.  Values are also clamped to [0, 255], with a signed value of 0 being
  79. // mapped to an unsigned (middle-gray) value of 128.
  80. //////////////////////////////////////////////////////////////////////////////////////////
  81. static void Quantize(short *p, unsigned long x, unsigned long y, long rowshorts, short depth)
  82. {
  83.     long        leftbound;
  84.     long        rightbound;
  85.     long        topbound;
  86.     long        bottombound;
  87.     long        min,max;
  88.     long        xindex, yindex;
  89.     short        *pCurrent;
  90.     long        currentAdjusted;
  91.     long        scale;
  92.     
  93.     if (depth) {
  94.  
  95.         ////////////////////////////////////////////////////////////
  96.         
  97.         leftbound = x/2;
  98.         rightbound = x;
  99.         topbound = 0;
  100.         bottombound = y/2;
  101.         min = 0;
  102.         max = 0;
  103.         
  104.         for (yindex = topbound; yindex < bottombound; yindex++) {
  105.             pCurrent = p + (yindex * rowshorts) + (leftbound * 4);
  106.             for (xindex = leftbound*4; xindex < rightbound*4; xindex++) {
  107.                 if (*pCurrent < min) min = *pCurrent;
  108.                 if (*pCurrent > max) max = *pCurrent;
  109.                 pCurrent++;
  110.             }
  111.         }
  112.         
  113.         scale = max;
  114.         if (-min > scale) scale = -min;
  115.  
  116.         for (yindex = topbound; yindex < bottombound; yindex++) {
  117.             pCurrent = p + (yindex * rowshorts) + (leftbound * 4);
  118.             for (xindex = leftbound*4; xindex < rightbound*4; xindex++) {
  119.                 currentAdjusted = *pCurrent * 128;
  120.                 currentAdjusted /= scale;
  121.                 *pCurrent = 66 - currentAdjusted;
  122.                 pCurrent++;
  123.             }
  124.         }
  125.  
  126.         ////////////////////////////////////////////////////////////
  127.         
  128.         leftbound = x/2;
  129.         rightbound = x;
  130.         topbound = y/2;
  131.         bottombound = y;
  132.         min = 0;
  133.         max = 0;
  134.         
  135.         for (yindex = topbound; yindex < bottombound; yindex++) {
  136.             pCurrent = p + (yindex * rowshorts) + (leftbound * 4);
  137.             for (xindex = leftbound*4; xindex < rightbound*4; xindex++) {
  138.                 if (*pCurrent < min) min = *pCurrent;
  139.                 if (*pCurrent > max) max = *pCurrent;
  140.                 pCurrent++;
  141.             }
  142.         }
  143.         
  144.         scale = max;
  145.         if (-min > scale) scale = -min;
  146.  
  147.         for (yindex = topbound; yindex < bottombound; yindex++) {
  148.             pCurrent = p + (yindex * rowshorts) + (leftbound * 4);
  149.             for (xindex = leftbound*4; xindex < rightbound*4; xindex++) {
  150.                 currentAdjusted = *pCurrent * 128;
  151.                 currentAdjusted /= scale;
  152.                 *pCurrent = 66 - currentAdjusted;
  153.                 pCurrent++;
  154.             }
  155.         }
  156.  
  157.         ////////////////////////////////////////////////////////////
  158.         
  159.         leftbound = 0;
  160.         rightbound = x/2;
  161.         topbound = y/2;
  162.         bottombound = y;
  163.         min = 0;
  164.         max = 0;
  165.         
  166.         for (yindex = topbound; yindex < bottombound; yindex++) {
  167.             pCurrent = p + (yindex * rowshorts) + (leftbound * 4);
  168.             for (xindex = leftbound*4; xindex < rightbound*4; xindex++) {
  169.                 if (*pCurrent < min) min = *pCurrent;
  170.                 if (*pCurrent > max) max = *pCurrent;
  171.                 pCurrent++;
  172.             }
  173.         }
  174.         
  175.         scale = max;
  176.         if (-min > scale) scale = -min;
  177.  
  178.         for (yindex = topbound; yindex < bottombound; yindex++) {
  179.             pCurrent = p + (yindex * rowshorts) + (leftbound * 4);
  180.             for (xindex = leftbound*4; xindex < rightbound*4; xindex++) {
  181.                 currentAdjusted = *pCurrent * 128;
  182.                 currentAdjusted /= scale;
  183.                 *pCurrent = 66 - currentAdjusted;
  184.                 pCurrent++;
  185.             }
  186.         }
  187.         
  188.         //////////////////////////////////////////////////////////////
  189.  
  190.  
  191.         Quantize(p, x/2, y/2, rowshorts, depth-1);
  192.  
  193.  
  194.     } else {
  195.  
  196.         leftbound = 0;
  197.         rightbound = x;
  198.         topbound = 0;
  199.         bottombound = y;
  200.         min = 0;
  201.         max = 0;
  202.         
  203.         for (yindex = topbound; yindex < bottombound; yindex++) {
  204.             pCurrent = p + (yindex * rowshorts) + (leftbound * 4);
  205.             for (xindex = leftbound*4; xindex < rightbound*4; xindex++) {
  206.                 *pCurrent = *pCurrent / 64;
  207.                 pCurrent++;
  208.             }
  209.         }
  210.             
  211.     }
  212.     
  213. }
  214.  
  215. static void Pack16To8(     signed short     *pSrc,
  216.                     unsigned char *pDest,
  217.                     unsigned long    length)
  218. {
  219.     signed short        element;
  220.     int                    i;
  221.     
  222.     for (i = 0; i<length; i++) {
  223.         element = *pSrc++;
  224.                 
  225.         *pDest++ = element;    
  226.     }
  227. }                        
  228.  
  229. #pragma mark -
  230.  
  231. //////////////////////////////////////////////
  232. // NewWindowWithData
  233. // Creates a new window with a CCopyBitsPane
  234. // that uses the specified pixmap with pixel
  235. // data stored in data handle.
  236. //////////////////////////////////////////////
  237. LWindow *CTransformPane::NewWindowWithData(const PixMap &pmap, Handle data)
  238. {
  239.     long        width = pmap.bounds.right-pmap.bounds.left;
  240.     long        height = pmap.bounds.bottom-pmap.bounds.top;
  241.  
  242.     LWindow        *pWin = PP_PowerPlant::LWindow::CreateWindow(129, LCommander::GetTopCommander());
  243.     ThrowIfNil_(pWin);
  244.     
  245.     CCopyBitsPane* pBitsPane = dynamic_cast<CCopyBitsPane*>(pWin->FindPaneByID('BMap'));
  246.     FailNIL_(pBitsPane);
  247.     
  248.     pBitsPane->SetPixelData(pmap, data, mPaddedX, mPaddedY);
  249.     
  250.     LCommander::SwitchTarget(pBitsPane);
  251.  
  252.     pWin->ResizeWindowTo(width, height);
  253.  
  254.     // LWindow is not initially visible in PPob resource
  255.     pWin->Show();
  256.     
  257.     // force a draw
  258.     pWin->UpdatePort();
  259.     
  260.     return pWin;
  261. }
  262.  
  263.  
  264.  
  265.  
  266. CTransformPane::CTransformPane(    LStream            *inStream)
  267. :CCopyBitsPane(inStream)
  268. {
  269. }
  270.  
  271. CTransformPane::~CTransformPane()
  272. {
  273. }    
  274.  
  275. void
  276. CTransformPane::FindCommandStatus(
  277.     CommandT    inCommand,
  278.     Boolean        &outEnabled,
  279.     Boolean        &outUsesMark,
  280.     Char16        &outMark,
  281.     Str255        outName)
  282. {
  283.     switch (inCommand) {
  284.     
  285.         case cmd_WaveletTransform:
  286.             outEnabled = true;
  287.             break;
  288.             
  289.         
  290.         default:
  291.             LCommander::FindCommandStatus(inCommand, outEnabled,
  292.                                     outUsesMark, outMark, outName);
  293.             break;
  294.     }
  295. }
  296.  
  297.  
  298.  
  299. void 
  300. CTransformPane::DoTransform()
  301. {            
  302.     StHandleLocker    lockBits(mBitsData);
  303.  
  304.     LWindow            *pCreatedWindow;
  305.  
  306.     long            width = mPaddedX;
  307.     long            height = mPaddedY;
  308.  
  309.     StHandleBlock    tempBlock(width*height*4*sizeof(short));
  310.     StHandleBlock    transformBlock(width*height*4*sizeof(short));
  311.     StHandleBlock    recoveredBlock(width*height*4*sizeof(char));
  312.  
  313.     StHandleLocker    lockTemp(tempBlock);
  314.     StHandleLocker    lockTransform(transformBlock);
  315.         
  316.     long            tickstart = TickCount();
  317.  
  318.  
  319. #if __VEC__        
  320.     // perform forward vector wavelet 
  321.     vFWVT_4_Quad16_2DInt((long *)*mBitsData.Get(),
  322.                     (long*)*transformBlock.Get(),
  323.                     (long*)*tempBlock.Get(),
  324.                     width,
  325.                     height,
  326.                     width,
  327.                     WAVELET_32_DEPTH);
  328.  
  329. #else
  330.  
  331.     // perform forward scalar wavelet 
  332.     sFWVT_4_Quad16_2DInt((short *)*mBitsData.Get(),
  333.                     (short*)*transformBlock.Get(),
  334.                     (short*)*tempBlock.Get(),
  335.                     width,
  336.                     height,
  337.                     width,
  338.                     WAVELET_32_DEPTH);
  339.  
  340.  
  341. #endif
  342.  
  343.  
  344.     Handle        copiedHandle = transformBlock.Get();
  345.     FailOSErr_(HandToHand(&copiedHandle));
  346.     
  347.     StHandleBlock        adjustedWaveBlock(copiedHandle);
  348.     
  349.     {
  350.         StHandleLocker        lock(adjustedWaveBlock);
  351.         
  352.         Quantize((short*)*adjustedWaveBlock.Get(), width, height, width*4, WAVELET_32_DEPTH);
  353.     }
  354.                 
  355.     Pack16To8((short*)*adjustedWaveBlock.Get(), (unsigned char*)*adjustedWaveBlock.Get(), ::GetHandleSize(adjustedWaveBlock)/2);
  356.     
  357.     ::SetHandleSize(adjustedWaveBlock, ::GetHandleSize(adjustedWaveBlock)/2);
  358.     
  359.     pCreatedWindow = NewWindowWithData(mPixMap, adjustedWaveBlock);        
  360.     
  361.     pCreatedWindow->SetDescriptor("\pWavelet Transform Data");
  362.  
  363.     adjustedWaveBlock.Release();
  364.     
  365.     ////////////////////////////////
  366.     // now do inverse wavelet and
  367.     // display result
  368.     ////////////////////////////////
  369.  
  370. #if __VEC__        
  371.     // perform forward vector wavelet 
  372.     vIFWVT_4_Quad16_2DInt((long *)*transformBlock.Get(),
  373.                     (long*)*recoveredBlock.Get(),
  374.                     (long*)*tempBlock.Get(),
  375.                     width,
  376.                     height,
  377.                     width,
  378.                     WAVELET_32_DEPTH);
  379.  
  380. #else
  381.  
  382.     // perform forward scalar wavelet 
  383.     sIFWVT_4_Quad16_2DInt((short *)*transformBlock.Get(),
  384.                     (short*)*recoveredBlock.Get(),
  385.                     (short*)*tempBlock.Get(),
  386.                     width,
  387.                     height,
  388.                     width,
  389.                     WAVELET_32_DEPTH);
  390.  
  391.  
  392. #endif
  393.  
  394.     pCreatedWindow = NewWindowWithData(mPixMap, recoveredBlock);
  395.     
  396.     pCreatedWindow->SetDescriptor("\pRecovered Image");
  397.     
  398.     recoveredBlock.Release();        
  399.  
  400.     
  401. }
  402.  
  403.  
  404.  
  405. Boolean
  406. CTransformPane::ObeyCommand(
  407.     CommandT    inCommand,
  408.     void*        ioParam)
  409. {
  410.     Boolean    cmdHandled = false;
  411.  
  412.     switch (inCommand) {
  413.     
  414.         case cmd_WaveletTransform:
  415.             DoTransform();
  416.             cmdHandled = true;
  417.             break;
  418.             
  419.         default:
  420.             cmdHandled = LCommander::ObeyCommand(inCommand, ioParam);
  421.             break;
  422.     }
  423.  
  424.     return cmdHandled;
  425.     
  426. }
  427.  
  428.  
  429.